/**
 * 数据拷贝
 * 
 * 直接拷贝
 * 浅拷贝
 * 深拷贝
 * 
 */

/**
 * 浅拷贝，问题：只能复制第1层
 * @param {*} obj 
 */
function clone(obj){
    
    if(typeof obj === 'object' && obj !== null){
        let res;
        if(Array.isArray(obj)){
            res=[]
            obj.forEach(item => {
                res.push(item)
            });
        }else{
            res={}
            Object.keys(obj).forEach(key => {
                res[key]= obj[key]
            });
        }
        return res;
    }else{
        return obj;
    }
}

// 
/**
 * 深拷贝1,使用json格式化再转为对象，仅仅适用于只有字面量数据
 * 问题：
 * 1.函数类型的属性丢失了，
 * 2.循环引用会报错
 * @param {*} obj 
 * @returns 
 */
function deepClone1(obj){
    if(typeof obj === 'object' && obj !== null){
        try {
            return JSON.parse(JSON.stringify(obj))
        } catch (error) {
            console.error(error)
            return null
        }
        
    }else{
        return obj;
    }
    
}

/**
 * 深拷贝2,使用递归方式拷贝数据
 * 解决问题：
 * 1.函数类型的属性丢失了，
 * 2.循环引用会报错的问题(通过map缓存当前对象的值，要是下次找到就直接返回)
 * @param {*} obj
 * @param {Map} map 缓存互相引用的对象
 * @returns 
 */
function deepClone2(obj,map=new Map()){
    if(typeof obj=== 'object' && obj!==null){
       
        const cache=map.get(obj);
        if(cache){
                return cache;
        }
        let res=Array.isArray(obj)?[]:{};
        // 先缓存res到map,然后后面res更新也会自动更新
        map.set(obj,res)
        if(Array.isArray(obj)){
            obj.forEach((item,index)=>{
                res[index]=deepClone2(item,map)
            })
        }else{
                Object.keys(obj).forEach(key=>{
                    res[key]=deepClone2(obj[key],map) 
                })
        }
        return res;
    }else{
        return obj;
    }
}


/**
 * 深拷贝3,使用递归方式拷贝数据
 * 解决问题：
 * 1.Date Reg Set Map Math，
 * 2.优化缓存对象
 * @param {*} obj
 * @param {Map} map 缓存互相引用的对象
 * @returns 
 */
function deepClone3(obj,map=new Map()){
    if(typeof obj=== 'object' && obj!==null){
       
        const cache=map.get(obj);
        if(cache){
                return cache;
        }
        let res=Array.isArray(obj)?[]:{};
        // 先缓存res到map,然后后面res更新也会自动更新
        map.set(obj,res)
        if(Array.isArray(obj)){
            obj.forEach((item,index)=>{
                res[index]=deepClone2(item,map)
            })
        }else{
                Object.keys(obj).forEach(key=>{
                    res[key]=deepClone2(obj[key],map) 
                })
        }
        return res;
    }else{
        return obj;
    }
}





